<template>
    <el-card class="box-card">

        <!-- 新增/修改弹出框 -->
        <el-dialog :title="dialogTitle + '配置'" :visible.sync="dialogAddOrUpdate" width="40%"
            :before-close="handleCloseUpdate">
            <el-form :model="configForm" :rules="configFormRules" ref="configForm" label-width="100px">
                <el-form-item label="配置键" prop="configKey">
                    <el-input v-model="configForm.configKey" placeholder="请输入配置键，例如：site.author"></el-input>
                </el-form-item>
                
                <el-form-item label="配置类型" prop="configType">
                    <el-select v-model="configForm.configType" placeholder="请选择配置类型" style="width: 100%">
                        <el-option v-for="item in configTypes" :key="item.value" :label="item.label" :value="item.value">
                        </el-option>
                    </el-select>
                </el-form-item>
                
                <el-form-item label="配置描述" prop="description">
                    <el-input v-model="configForm.description" placeholder="请输入配置描述"></el-input>
                </el-form-item>
                
                <div class="config-value-section">
                    <div class="config-value-header">
                        <span class="config-value-title">配置值</span>
                        <el-tag v-if="configForm.configType === 'JSON'" type="success" size="small">可自由扩充子项</el-tag>
                        <el-tag v-else type="info" size="small">普通文本</el-tag>
                    </div>
                    
                    <template v-if="configForm.configType === 'JSON'">
                        <div class="json-config-info">
                            <el-alert
                                title="JSON配置使用说明"
                                type="info"
                                description="1. 字段名包含avatar、image等关键词的将自动显示为图片上传组件
2. 可以通过添加自定义字段功能扩充配置项
3. 支持嵌套对象，如social.github表示social对象下的github属性"
                                show-icon
                                :closable="false">
                            </el-alert>
                        </div>
                        <dynamic-form-item :value-obj="configForm.configValueObj" label-prefix=""
                            prop-prefix="configValueObj." :key="dynamicFormKey" @field-deleted="onFieldDeleted" />
                            
                        <div class="add-field-section">
                            <div class="add-field-header">
                                <span>添加自定义字段</span>
                                <el-tooltip content="可以添加新的配置项或嵌套对象" placement="top">
                                    <i class="el-icon-question"></i>
                                </el-tooltip>
                            </div>
                            <div class="add-field-form">
                                <el-row :gutter="10">
                                    <el-col :span="6">
                                        <el-tooltip placement="top" effect="light">
                                            <div slot="content">字段路径 (如: social.weixin)<br/>使用点号分隔嵌套层级</div>
                                            <el-input v-model="newField.path" placeholder="字段路径"></el-input>
                                        </el-tooltip>
                                    </el-col>
                                    <el-col :span="6">
                                        <el-select v-model="newField.type" placeholder="值类型" style="width: 100%">
                                            <el-option label="文本" value="string"></el-option>
                                            <el-option label="数字" value="number"></el-option>
                                            <el-option label="布尔值" value="boolean"></el-option>
                                            <el-option label="对象" value="object"></el-option>
                                            <el-option label="数组" value="array"></el-option>
                                            <el-option label="图片" value="image"></el-option>
                                        </el-select>
                                    </el-col>
                                    <el-col :span="6">
                                        <el-input v-model="newField.value" placeholder="字段值"></el-input>
                                    </el-col>
                                    <el-col :span="6">
                                        <el-button type="primary" @click="addCustomField">添加字段</el-button>
                                    </el-col>
                                </el-row>
                            </div>
                        </div>
                    </template>
                    <template v-else>
                        <el-form-item label="配置值" prop="configValue">
                            <el-input v-model="configForm.configValue" type="textarea" :rows="4" 
                                placeholder="请输入配置值内容"></el-input>
                        </el-form-item>
                    </template>
                </div>

                <el-form-item>
                    <el-button type="primary" @click="submitUpdateForm('configForm')">立即{{ dialogTitle }}</el-button>
                    <el-button @click="resetForm('configForm')">重置</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>

        <!-- 搜索栏 -->
        <div class="select-div">

            <my-select v-model="condition.configType" placeholder="配置类型" :showList="configTypes" labelName='label'
                valueName='value' />

            <el-input clearable v-model="condition.keywords" prefix-icon="el-icon-search" size="small"
                placeholder="请输入配置键关键字" style="width:200px" @keyup.enter.native="searchConfigs" />

            <el-button type="primary" size="small" icon="el-icon-search" style="margin-left:1rem"
                @click="searchConfigs">搜索</el-button>

            <el-button type="primary" size="small" icon="el-icon-plus" @click="dialogAdd">新增</el-button>

            <el-button type="danger" size="small" icon="el-icon-delete" @click="deleteCheck()"
                :disabled="this.selection.length === 0">删除选中</el-button>

        </div>

        <!-- 表格内容 -->
        <el-table :data="tableData" border :header-cell-style="{ 'text-align': 'center' }"
            :cell-style="{ 'text-align': 'center' }" @selection-change="handleSelectionChange">
            
            <el-table-column type="selection" width="55"></el-table-column>

            <el-table-column prop="configKey" label="配置键" sortable></el-table-column>

            <el-table-column prop="configValue" label="配置值">
                <template slot-scope="scope">
                    <template v-if="scope.row.configType === 'JSON'">
                        <div class="config-value-cell json-preview">
                            <el-popover
                                placement="right"
                                width="400"
                                trigger="hover">
                                <div class="json-structure">
                                    <pre>{{ formatJson(scope.row.configValue) }}</pre>
                                </div>
                                <el-button slot="reference" type="text">查看完整JSON结构</el-button>
                            </el-popover>
                        </div>
                    </template>
                    <template v-else>
                        <div class="config-value-cell">
                            {{ scope.row.configValue }}
                        </div>
                    </template>
                </template>
            </el-table-column>

            <el-table-column prop="configType" label="配置类型" sortable></el-table-column>

            <el-table-column prop="description" label="配置描述"></el-table-column>

            <el-table-column prop="createTime" label="创建时间" sortable></el-table-column>

            <el-table-column prop="updateTime" label="更新时间" sortable></el-table-column>

            <el-table-column label="操作" fixed="right" width="100">
                <template slot-scope="scope">
                    <el-tooltip effect="dark" content="编辑" placement="top-start">
                        <el-button circle icon="el-icon-edit" size="mini" @click="dialogUpdate(scope.row.id)" />
                    </el-tooltip>

                    <el-tooltip effect="dark" content="删除" placement="top-start">
                        <el-button circle icon="el-icon-delete" size="mini" placement="top-start" type="danger"
                            @click="deleteCheck(scope.row.id)"/>
                    </el-tooltip>
                </template>
            </el-table-column>
        </el-table>

        <!-- 分页 -->
        <pagination :total="total" :page_index="pageNum" @pageChange="pageChange" />

    </el-card>
</template>

<script>
import DynamicFormItem from '@/components/DynamicFormItem/index.vue';
import { configApi } from '@/api';

export default {
    data() {
        return {
            tableData: [],
            total: 0,
            pageNum: 1,
            pageSize: 10,
            selection: [],
            selectedNum: 0,
            configForm: {
                configKey: '',
                configType: '',
                configValue: '',
                description: '',
                configValueObj: {}
            },
            configTypes: [],
            dialogAddOrUpdate: false,
            dialogTitle: '',
            condition: {
                keywords: null,
                configType: null
            },
            configFormRules: {
                configKey: [
                    { required: true, message: '请输入配置键', trigger: 'blur' }
                ],
                configType: [
                    { required: true, message: '请选择配置类型', trigger: 'change' }
                ]
            },
            newField: {
                path: '',
                value: '',
                type: 'string'
            },
            dynamicFormKey: 0
        }
    },

    methods: {
        /**
         * 复选框事件
         * @param selection 选中数据数组
         */
        handleSelectionChange(selection) {
            this.selection = selection.map(item => item.id)
            this.selectedNum = selection.length
        },

        /**
         * 删除数据
         * @param id 数据id
         */
        deleteCheck(id) {
            this.$confirm("确认删除选中记录吗？", "提示", {
                type: "warning"
            }).then(() => {
                const ids = id == null ? this.selection : [id];
                configApi.deleteConfigs(ids).then((response) => {
                    if (response.data.code === 20000) {
                        this.$message({
                            message: '删除成功！',
                            type: 'success'
                        });
                        this.loadConfigList();
                    }
                });
            }).catch(() => {
                // 取消删除操作
            });
        },

        pageChange(val) {
            this.pageNum = val.pageNum;
            this.pageSize = val.pageSize;
            this.loadConfigList();
        },

        dialogAdd() {
            this.dialogTitle = "新增";
            this.configForm = {
                configKey: '',
                configType: '',
                configValue: '',
                description: '',
                configValueObj: {}
            };
            this.dialogAddOrUpdate = true;
            // 确保DOM更新后再重置上传组件
            this.$nextTick(() => {
                if (this.$refs.upload) {
                    this.$refs.upload.resetFile();
                }
            });
        },

        searchConfigs() {
            this.pageNum = 1;
            this.loadConfigList();
        },

        handleCloseUpdate() {
            this.$refs.configForm.resetFields();
            this.configForm = {
                configKey: '',
                configType: '',
                configValue: '',
                description: '',
                configValueObj: {}
            };
            this.dialogAddOrUpdate = false;
        },

        resetForm(formName) {
            this.$refs[formName].resetFields();
            this.configForm = {
                configKey: '',
                configType: '',
                configValue: '',
                description: '',
                configValueObj: {}
            };
            this.newField = {
                path: '',
                value: '',
                type: 'string'
            };
        },

        /**
         * 编辑
         * @param id 配置ID
         */
        dialogUpdate(id) {
            configApi.getConfigInfo(id).then((response) => {
                if (response.data.code === 20000) {
                    this.configForm = response.data.data;

                    // 如果是JSON类型，解析configValue为对象
                    if (this.configForm.configType === 'JSON' && typeof this.configForm.configValue === 'string') {
                        try {
                            this.configForm.configValueObj = JSON.parse(this.configForm.configValue);
                        } catch (e) {
                            console.error('JSON解析错误', e);
                            this.configForm.configValueObj = {};
                        }
                    }

                    this.dialogTitle = "修改";
                    this.dialogAddOrUpdate = true;
                    // 确保DOM更新后再重置上传组件
                    this.$nextTick(() => {
                        if (this.$refs.upload) {
                            this.$refs.upload.resetFile();
                        }
                    });
                }
            });
        },

        /**
         * 提交更新表单
         * @param formName 表单名称
         */
        submitUpdateForm(formName) {
            this.$refs[formName].validate((valid) => {
                if (valid) {
                    let data = { ...this.configForm };

                    // 如果是JSON类型，将configValueObj转为字符串
                    if (this.configForm.configType === 'JSON') {
                        // 检查JSON对象是否为空
                        if (Object.keys(this.configForm.configValueObj).length === 0) {
                            this.$message.error('JSON配置值不能为空，请至少添加一个字段');
                            return;
                        }
                        data.configValue = JSON.stringify(this.configForm.configValueObj);
                    } else if (!this.configForm.configValue) {
                        this.$message.error('配置值不能为空');
                        return;
                    }

                    const apiMethod = this.configForm.id ? configApi.updateConfig : configApi.addConfig;
                    apiMethod(data).then((response) => {
                        if (response.data.code === 20000) {
                            this.$message({
                                showClose: true,
                                message: '操作成功！',
                                type: 'success',
                                onClose: () => {
                                    this.loadConfigList();
                                }
                            });
                        }
                    });
                    this.dialogAddOrUpdate = false;
                    this.resetForm(formName);
                } else {
                    return false;
                }
            });
        },

        /**
         * 获取网站配置列表
         */
        loadConfigList() {
            const params = {
                pageNum: this.pageNum,
                pageSize: this.pageSize,
                keywords: this.condition.keywords,
                configType: this.condition.configType
            };
            
            configApi.getConfigList(params).then((response) => {
                if (response.data.code === 20000) {
                    if (response.data.data != null) {
                        this.tableData = response.data.data.pagingList;
                        this.total = response.data.data.count;
                        return;
                    }
                    this.tableData = null;
                    this.total = null;
                }
            }).catch((error) => {
                this.$message.error("获取配置列表失败！");
            });
        },

        /**
         * 获取配置类型列表
         */
        getConfigTypes() {
            configApi.getConfigTypes().then((response) => {
                if (response.data.code === 20000) {
                    this.configTypes = response.data.data;
                }
            }).catch((error) => {
                this.$message.error("获取配置类型列表失败！");
            });
        },

        /**
         * 添加自定义字段到配置值对象
         */
        addCustomField() {
            if (!this.newField.path) {
                this.$message.warning('请输入字段路径');
                return;
            }
            
            try {
                // 分割路径字符串，如 "social.weixin" => ["social", "weixin"]
                const pathParts = this.newField.path.split('.');
                let current = this.configForm.configValueObj;
                
                // 遍历路径，确保每一级对象都存在
                for (let i = 0; i < pathParts.length - 1; i++) {
                    const part = pathParts[i];
                    if (!current[part]) {
                        current[part] = {};
                    }
                    current = current[part];
                }
                
                // 根据类型设置值
                const lastPart = pathParts[pathParts.length - 1];
                if (this.newField.type === 'number') {
                    current[lastPart] = Number(this.newField.value);
                } else if (this.newField.type === 'boolean') {
                    current[lastPart] = this.newField.value === 'true';
                } else {
                    current[lastPart] = this.newField.value;
                }
                
                // 更新表单，触发视图更新
                this.dynamicFormKey++;
                
                // 清空输入
                this.newField = {
                    path: '',
                    value: '',
                    type: 'string'
                };
                
                this.$message.success('字段添加成功');
            } catch (error) {
                this.$message.error('添加字段失败: ' + error.message);
            }
        },
        
        /**
         * 删除JSON配置中的字段
         */
        removeJsonField(path) {
            try {
                const pathParts = path.split('.');
                let current = this.configForm.configValueObj;
                
                // 如果是顶级属性
                if (pathParts.length === 1) {
                    delete current[pathParts[0]];
                    this.dynamicFormKey++;
                    return;
                }
                
                // 找到要删除属性的父对象
                for (let i = 0; i < pathParts.length - 1; i++) {
                    current = current[pathParts[i]];
                    if (!current) return;
                }
                
                // 删除属性
                delete current[pathParts[pathParts.length - 1]];
                
                // 更新表单，触发视图更新
                this.dynamicFormKey++;
                
                this.$message.success('字段删除成功');
            } catch (error) {
                this.$message.error('删除字段失败: ' + error.message);
            }
        },
        
        /**
         * 递归渲染JSON对象为扁平化的路径列表
         */
        flattenJsonObject(obj, prefix = '') {
            let result = [];
            
            for (const key in obj) {
                const path = prefix ? `${prefix}.${key}` : key;
                const value = obj[key];
                
                if (typeof value === 'object' && value !== null) {
                    // 递归处理嵌套对象
                    result = result.concat(this.flattenJsonObject(value, path));
                } else {
                    // 添加叶子节点
                    result.push({
                        path,
                        value,
                        type: typeof value
                    });
                }
            }
            
            return result;
        },

        /**
         * 处理字段删除事件
         */
        onFieldDeleted() {
            // 强制刷新动态表单
            this.dynamicFormKey++;
        },

        /**
         * 格式化JSON字符串
         */
        formatJson(jsonString) {
            try {
                const obj = typeof jsonString === 'string' ? JSON.parse(jsonString) : jsonString;
                return JSON.stringify(obj, null, 2);
            } catch (e) {
                return jsonString;
            }
        }
    },

    created() {
        this.loadConfigList();
        this.getConfigTypes();
    },

    components: { DynamicFormItem }
}
</script>

<style scoped>
.config-value-cell {
    max-height: 100px;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 4;
    /* 你可以根据实际需要调整显示的行数 */
    -webkit-box-orient: vertical;
    word-break: break-all;
    white-space: normal;
}

.config-value-section {
    margin: 15px 0;
    border: 1px solid #e6ebf5;
    border-radius: 4px;
    padding: 15px;
    background-color: #f5f7fa;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}

.config-value-header {
    display: flex;
    align-items: center;
    margin-bottom: 15px;
    padding-bottom: 10px;
    border-bottom: 1px dashed #dcdfe6;
}

.config-value-title {
    font-size: 16px;
    font-weight: bold;
    color: #409EFF;
    margin-right: 10px;
}

.json-config-info {
    margin-bottom: 20px;
}

.json-preview {
    display: flex;
    align-items: center;
    justify-content: center;
}

.json-structure {
    max-height: 400px;
    overflow: auto;
}

.json-structure pre {
    margin: 0;
    white-space: pre-wrap;
    font-family: monospace;
    font-size: 12px;
}

.add-field-section {
    margin-top: 20px;
    padding: 15px;
    background-color: #fff;
    border: 1px dashed #dcdfe6;
    border-radius: 4px;
}

.add-field-header {
    margin-bottom: 15px;
    font-weight: bold;
    color: #606266;
    display: flex;
    align-items: center;
}

.add-field-header i {
    margin-left: 5px;
    color: #909399;
    cursor: help;
}

.add-field-form {
    margin-bottom: 10px;
}
</style>